package Main;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import Utils.LoadingCenter;
import Utils.MiscUtils;
import Utils.Concurrent.AsyncTask;
import Utils.Concurrent.Loader;
import Utils.Concurrent.TaskPool;
import Utils.Graphics.LoadingWheel;
import Utils.UI.UIUpdater;

public class GuiMain {

	/**
	 * @param args
	 */

	static TaskPool<String> namePool;
	static TaskPool<String> LongOpPool;
	public static LoadingWheel wheel;
	static String result;

	public synchronized static void setResults(String newResult) {
		result = newResult;
	}

	public synchronized static String getResults() {
		return result;
	}

	private static void initLoadingWheel(Display display) {
		wheel = LoadingWheel
				.getInfiniteProgressPanelFor(display.getShells()[0]);
		wheel.setText("Please wait...");
		wheel.setTextColor(display.getSystemColor(SWT.COLOR_DARK_RED));
		wheel.setTextFont(new Font(display, "Lucida Sans", 18, SWT.BOLD));
	}

	public static void main(String[] args) {

		// Initialize settings for application
		MiscUtils.prepareProgram();

		Display display = new Display();
		final Shell shell = new Shell(display);
		shell.setSize(600, 600);
		shell.setLayout(new GridLayout());

		// LoadingTest(shell, display);

		CheckingNameTester(shell, display);

		LongOperationTester(shell, display);

		initLoadingWheel(display);

		// shell.pack();
		shell.open();

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}

		namePool.close();
		LongOpPool.close();
		display.dispose();

	}

	public static void LoadingTest(final Shell shell, Display display) {
		final Label actorsLabel = new Label(shell, SWT.BORDER | SWT.HORIZONTAL);
		actorsLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		actorsLabel.setText("parsing actors..");
		actorsLabel.setSize(200, 20);

		final Label programsLabel = new Label(shell, SWT.BORDER
				| SWT.HORIZONTAL);
		programsLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		programsLabel.setText("parsing programs..");
		programsLabel.setSize(200, 20);

		final Label filmsLabel = new Label(shell, SWT.BORDER | SWT.HORIZONTAL);
		filmsLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		filmsLabel.setText("parsing films..");
		filmsLabel.setSize(200, 20);

		final Label filmActorsLabel = new Label(shell, SWT.BORDER
				| SWT.HORIZONTAL);
		filmActorsLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		filmActorsLabel.setText("parsing film actors..");
		filmActorsLabel.setSize(200, 20);

		Button b = new Button(shell, SWT.HORIZONTAL);
		b.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		b.setText("check response");

		b.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetDefaultSelected(SelectionEvent arg0) {
			}

			@Override
			public void widgetSelected(SelectionEvent arg0) {
				MessageBox messageBox = new MessageBox(shell, SWT.OK);

				messageBox.setText("response test");
				messageBox.setMessage("checking response..");
				messageBox.open();
			}
		});

		LoadingCenter.Load_tvActors(display, actorsLabel);
		LoadingCenter.Load_tvPrograms(display, programsLabel);
		LoadingCenter.Load_Films(display, filmsLabel);
		LoadingCenter.Load_filmActors(display, filmActorsLabel);
	}

	public static void CheckingNameTester(final Shell shell, Display display) {
		final Label loadingLabel = new Label(shell, SWT.BORDER | SWT.HORIZONTAL);
		loadingLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		loadingLabel.setText("");
		loadingLabel.setSize(200, 20);

		final Text nameTxt = new Text(shell, SWT.BORDER | SWT.HORIZONTAL);
		nameTxt.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		nameTxt.setText("enter name");
		nameTxt.setSize(200, 20);

		final CheckNameSimulator checkNameWorker = new CheckNameSimulator(
				display, loadingLabel);

		// create task pool
		namePool = new TaskPool<String>(1);

		nameTxt.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent event) {
				switch (event.keyCode) {
				default: {
					if (nameTxt.getText().equals("enter name")) {
						nameTxt.setText("");
					}

					// push task to the front and shutdown others
					namePool.pushUrgentTask(checkNameWorker);

					break;
				}
				}
			}
		});

		nameTxt.addMouseListener(new MouseListener() {
			public void mouseDown(MouseEvent e) {
				if (nameTxt.getText().equals("enter name")) {
					nameTxt.setText("");
				}
			}

			@Override
			public void mouseDoubleClick(MouseEvent arg0) {
			}

			@Override
			public void mouseUp(MouseEvent arg0) {
			}

		});

	}

	private static void LongOperationTester(final Shell shell,
			final Display display) {

		final Label loadingLabel = new Label(shell, SWT.BORDER | SWT.HORIZONTAL);
		loadingLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		loadingLabel.setText("");
		loadingLabel.setSize(200, 20);

		final Label loaderLabel = new Label(shell, SWT.BORDER | SWT.HORIZONTAL);
		loaderLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		loaderLabel.setText("");
		loaderLabel.setSize(200, 20);

		final Button loadButton = new Button(shell, SWT.HORIZONTAL);
		loadButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		loadButton.setText("load");

		final Button nextButton = new Button(shell, SWT.HORIZONTAL);
		nextButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		nextButton.setText("next");
		nextButton.setVisible(false);

		final Button levelFinish = new Button(shell, SWT.HORIZONTAL);
		levelFinish.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		levelFinish.setText("finish level");
		levelFinish.setEnabled(false);
		levelFinish.setVisible(false);

		// create task pool
		LongOpPool = new TaskPool<String>(4);

		final LongOpSimulator longTask = new LongOpSimulator(display,
				loadingLabel, nextButton);

		loadButton.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetDefaultSelected(SelectionEvent arg0) {
			}

			@Override
			public void widgetSelected(SelectionEvent arg0) {

				loadButton.setVisible(false);
				levelFinish.setEnabled(true);
				levelFinish.setVisible(true);
				LongOpPool.addTaskToPool(true, longTask);

			}
		});

		nextButton.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetDefaultSelected(SelectionEvent arg0) {
			}

			@Override
			public void widgetSelected(SelectionEvent arg0) {
				loadButton.setVisible(true);
				nextButton.setVisible(false);
				loadingLabel.setText("");
				loaderLabel.setText("");

				/* --------- waiting for result ---------- */

				List<String> results = LongOpPool.getResults(longTask);
				MessageBox messageBox = new MessageBox(shell, SWT.OK);
				messageBox.setText("result test");
				messageBox.setMessage(results.get(0));
				messageBox.open();

			}
		});

		levelFinish.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetDefaultSelected(SelectionEvent arg0) {
			}

			@Override
			public void widgetSelected(SelectionEvent arg0) {
				levelFinish.setVisible(false);
				UIUpdater.setWidgetVisibile(nextButton, true);
				if (LongOpPool.hasRunningTask()) {

					wheel.start();
					
					loaderLabel.setVisible(false);
					
					 Loader loader_with_label = new Loader(display, "transition",
					 loaderLabel, nextButton, LongOpPool, longTask,
					 "preparing for next level", "ready for next level!");
					 

					Loader loader_with_wheel = new Loader(display, "wheel_transition",
							nextButton, LongOpPool, longTask, wheel);
					
					
					LongOpPool.addTaskToPool(true, loader_with_label);
					LongOpPool.addTaskToPool(true, loader_with_wheel);

				} else {
					nextButton.setEnabled(true);
				}

			}
		});
	}

	static class CheckNameSimulator extends AsyncTask<String> {

		public CheckNameSimulator(Display display, Object... vals) {
			super(display, vals);
		}

		@Override
		public String doInBackground() {
			Label loadingLabel = (Label) vals[0];
			String result = null;
			UIUpdater.setWidgetText(loadingLabel, "cheking availability");

			try {
				Thread.sleep(250);
				UIUpdater.setWidgetText(loadingLabel, "cheking availability.");

				Thread.sleep(250);
				UIUpdater.setWidgetText(loadingLabel, "cheking availability..");

				Thread.sleep(250);
				UIUpdater
						.setWidgetText(loadingLabel, "cheking availability...");

				Thread.sleep(250);

				int r = MiscUtils.GetRandomNumber(0, 10);
				if (r % 2 == 0) {
					result = "OK!";
				} else {
					result = "Unavailable!";
				}

				UIUpdater.setWidgetText(loadingLabel, result);

			} catch (Exception e) {
				// System.out.println(e);
			}

			return result;

		}

	}

	static class LongOpSimulator extends AsyncTask<String> {

		public LongOpSimulator(Display display, Object... vals) {
			super(display, vals);
		}

		@Override
		public String doInBackground() {
			Label loadingLabel = (Label) vals[0];
			Button nextButton = (Button) vals[1];

			try {
				UIUpdater.setWidgetText(loadingLabel, "working");
				Thread.sleep(650);
				UIUpdater.setWidgetText(loadingLabel, "working.");

				Thread.sleep(1200);
				UIUpdater.setWidgetText(loadingLabel, "working..");

				UIUpdater.setWidgetEnable(nextButton, false);

				Thread.sleep(1200);
				UIUpdater.setWidgetText(loadingLabel, "working...");

				Thread.sleep(1200);
				UIUpdater.setWidgetText(loadingLabel, "done!");

				Thread.sleep(650);

			} catch (Exception e) {
				// System.out.println(e);
			}
			UIUpdater.setWidgetText(loadingLabel, "");

			return "simulation completed!";
		}

	}
}
